package com.github.pig.admin.service.sys.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.pig.admin.common.util.TreeUtil;
import com.github.pig.admin.mapper.sys.SysUserMapper;
import com.github.pig.admin.model.dto.UserDTO;
import com.github.pig.admin.model.dto.UserInfo;
import com.github.pig.admin.model.entity.*;
import com.github.pig.admin.model.zhgl.community.CommunityInfo;
import com.github.pig.admin.model.zhgl.community.SelectBean;
import com.github.pig.admin.service.sys.*;
import com.github.pig.admin.service.zhgl.community.ICommunityInfoService;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.util.R;
import com.github.pig.common.util.SendMsgUtil;
import com.github.pig.common.util.UserUtils;
import com.github.pig.common.vo.CommunityInfoBean;
import com.github.pig.common.vo.SysRole;
import com.github.pig.common.vo.UserVO;
import com.xiaoleilu.hutool.collection.CollectionUtil;
import com.xiaoleilu.hutool.util.RandomUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author lengleng
 * @date 2017/10/31
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysDeptRelationService sysDeptRelationService;
    @Autowired
    private SysCommunityUserService sysCommunityUserService;
    @Resource
    private ICommunityInfoService communityInfoService;
    @Resource
    private SysDeptService sysDeptService;
    @Resource
    private SysUserService sysUserService;

    @Override
    public UserInfo findUserInfo(UserVO userVo) {
        SysUser condition = new SysUser();
        condition.setUsername(userVo.getUsername());
        SysUser sysUser = this.selectOne(new EntityWrapper<>(condition));

        UserInfo userInfo = new UserInfo();
        userInfo.setSysUser(sysUser);
        //设置角色列表
        List<SysRole> roleList = userVo.getRoleList();
        List<String> roleNames = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(roleList)) {
            for (SysRole sysRole : roleList) {
                if (!StrUtil.equals(SecurityConstants.BASE_ROLE, sysRole.getRoleName())) {
                    roleNames.add(sysRole.getRoleName());
                }
            }
        }
        String[] roles = roleNames.toArray(new String[roleNames.size()]);
        userInfo.setRoles(roles);
        //设置权限列表（menu.permission）
        String[] permissions = sysMenuService.findPermission(roles);
        userInfo.setPermissions(permissions);
        return userInfo;
    }

    @Override
    public UserVO findUserByUsername(String username) {
        return sysUserMapper.selectUserVoByUsername(username);
    }

    /**
     * 通过手机号查询用户信息
     *
     * @param mobile 手机号
     * @return 用户信息
     */
    @Override
    public UserVO findUserByMobile(String mobile) {
        return sysUserMapper.selectUserVoByMobile(mobile);
    }

    /**
     * 通过openId查询用户
     *
     * @param openId openId
     * @return 用户信息
     */
    @Override
    public UserVO findUserByOpenId(String openId) {
        return sysUserMapper.selectUserVoByOpenId(openId);
    }

    @Override
    public Page selectWithRolePage(Page page, String username) {
        Map<String, Object> map = new HashMap();
        UserVO user  = findUserByUsername(UserUtils.getUser());
        if(!CommonConstant.MANAGE_NAME.equals(user.getUsername())){
            map.put("communityIds", user.getCommunityList().stream().map(CommunityInfoBean::getCommunityId).collect(Collectors.toList()));
        }
          //map.put("deptIds",getChildCommunitys());
        map.put("username", username);
        page.setRecords(sysUserMapper.selectUserVoPageDataScope(page, map));
        return page;
    }

    /**
     * 通过ID查询用户信息
     *
     * @param id 用户ID
     * @return 用户信息
     */
    @Override
    public UserVO selectUserVoById(Integer id) {
        return sysUserMapper.selectUserVoById(id);
    }

    /**
     * 保存用户验证码，和randomStr绑定
     *
     * @param randomStr 客户端生成
     * @param imageCode 验证码信息
     */
    @Override
    public void saveImageCode(String randomStr, String imageCode) {
        redisTemplate.opsForValue().set(SecurityConstants.DEFAULT_CODE_KEY + randomStr, imageCode, SecurityConstants.DEFAULT_IMAGE_EXPIRE, TimeUnit.SECONDS);
    }

    /**
     * 发送验证码
     * <p>
     * 1. 先去redis 查询是否 60S内已经发送
     * 2. 未发送： 判断手机号是否存 ? false :产生4位数字  手机号-验证码
     * 3. 发往消息中心-》发送信息
     * 4. 保存redis
     *
     * @param mobile 手机号
     * @return true、false
     */
    @Override
    public R<Boolean> sendSmsCode(String mobile) {
        Object tempCode = redisTemplate.opsForValue().get(SecurityConstants.DEFAULT_CODE_KEY + mobile);
        if (tempCode != null) {
            log.error("用户:{}验证码未失效{}", mobile, tempCode);
            return new R<>(false, "验证码未失效，请失效后再次申请");
        }

        SysUser params = new SysUser();
        params.setPhone(mobile);
        List<SysUser> userList = this.selectList(new EntityWrapper<>(params));

        if (CollectionUtil.isEmpty(userList)) {
            log.error("根据用户手机号{}查询用户为空", mobile);
            //return new R<>(false, "手机号不存在");
        }

        String code = RandomUtil.randomNumbers(4);
        JSONObject contextJson = new JSONObject();
        contextJson.put("code", code);
        contextJson.put("product", "Pig4Cloud");
        log.info("短信发送请求消息中心 -> 手机号:{} -> 验证码：{}", mobile, code);
        try {
            SendMsgUtil.sendSmsByAliDayu(mobile, code);
        } catch (Exception e) {
            e.printStackTrace();
        }
        redisTemplate.opsForValue().set(SecurityConstants.DEFAULT_CODE_KEY + mobile, code, SecurityConstants.DEFAULT_IMAGE_EXPIRE, TimeUnit.SECONDS);
        return new R<>(true);
    }

    /**
     * 删除用户
     *
     * @param sysUser 用户
     * @return Boolean
     */
    @Override
    public Boolean deleteUserById(SysUser sysUser) {
        sysUserRoleService.deleteByUserId(sysUser.getUserId());
        this.deleteById(sysUser.getUserId());
        return Boolean.TRUE;
    }

    @Override
    public Boolean updateUserInfo(UserDTO userDto, String username) {
        UserVO userVo = this.findUserByUsername(username);

        SysUser sysUser = new SysUser();
        if (ENCODER.matches(userDto.getPassword(), userVo.getPassword())) {
            sysUser.setPassword(ENCODER.encode(userDto.getNewpassword1()));
        } else {
            return false;
        }
        sysUser.setUserId(userVo.getUserId());
        sysUser.setAvatar(userDto.getAvatar());
        if (StringUtils.isNotEmpty(userDto.getPhone())) {
            sysUser.setPhone(userDto.getPhone());
        }

        return this.updateById(sysUser);
    }

    @Override
    public Boolean updateUser(UserDTO userDto, String username) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(userDto, sysUser);
        sysUser.setUpdateTime(new Date());
        this.updateById(sysUser);

        SysUserRole condition = new SysUserRole();
        condition.setUserId(userDto.getUserId());
        condition.setType(CommonConstant.USER_ROLE_TYPE_YH);
        sysUserRoleService.delete(new EntityWrapper<>(condition));
        userDto.getRole().forEach(roleId -> {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(sysUser.getUserId());
            userRole.setType(CommonConstant.USER_ROLE_TYPE_YH);
            userRole.setRoleId(roleId);
            userRole.insert();
        });
        SysCommunityUser sCcondition = new SysCommunityUser();
        EntityWrapper scuWrapper = new EntityWrapper();
        scuWrapper.eq("user_id", userDto.getUserId());
        sCcondition.setUserId(userDto.getUserId().toString());
        List<SysCommunityUser> scu = sysCommunityUserService.selectList(scuWrapper);
        String defaultCommunityId = "";
        for (SysCommunityUser bean : scu) {
            if (CommonConstant.COMMUNITY_DEFAULT_FLAG.equals(bean.getDefaultFlag())) {
                defaultCommunityId = bean.getCommunityId();
            }
        }
        sysCommunityUserService.delete(new EntityWrapper<>(sCcondition));
        List<String> communitys = userDto.getCommunity();
        for (String communityId : communitys) {
            SysCommunityUser sysCommunityUser = new SysCommunityUser();
            if (defaultCommunityId.equals(communityId)) {
                sysCommunityUser.setDefaultFlag(CommonConstant.COMMUNITY_DEFAULT_FLAG);
            }
            sysCommunityUser.setUserId(sysUser.getUserId() + "");
            sysCommunityUser.setCommunityId(communityId);
            sysCommunityUser.insert();
        }

        return Boolean.TRUE;
    }

    /**
     * 获取当前用户的子部门信息
     *
     * @return 子部门列表
     */
    private List<String> getChildDepts() {
        //获取当前用户的部门
        String username = UserUtils.getUser();
        UserVO userVo = findUserByUsername(username);
        String deptId = userVo.getDeptId();

        //获取当前部门的子部门
        SysDeptRelation deptRelation = new SysDeptRelation();
        deptRelation.setAncestor(deptId);
        List<SysDeptRelation> deptRelationList = sysDeptRelationService.selectList(new EntityWrapper<>(deptRelation));
        List<String> deptIds = new ArrayList<>();
        for (SysDeptRelation sysDeptRelation : deptRelationList) {
            deptIds.add(sysDeptRelation.getDescendant());
        }
        return deptIds;
    }

    /**
     * 获取当前用户的小区信息
     *
     * @return 子部门列表
     */
    private List<String> getChildCommunitys() {
        //获取当前用户的部门
        String username = UserUtils.getUser();
        UserVO userVo = findUserByUsername(username);
        if (CommonConstant.MANAGE_NAME.equals(username)) {
            return null;
        }
        //获取当前部门的子部门
        EntityWrapper entityWrapper = new EntityWrapper();
        entityWrapper.eq("default_flag", CommonConstant.STATUS_NORMAL);
        entityWrapper.eq("user_id", userVo.getUserId());
        List<SysCommunityUser> deptRelationList = sysCommunityUserService.selectList(entityWrapper);

        List<String> communityIds = new ArrayList<>();
        for (SysCommunityUser bean : deptRelationList) {
            communityIds.add(bean.getCommunityId());
            //获取园区下的企业
            EntityWrapper deptWrapper = new EntityWrapper();
            deptWrapper.eq("del_flag", CommonConstant.STATUS_NORMAL);
            deptWrapper.eq("parent_id", bean.getCommunityId());
            List<SysDept> sysDepts = sysDeptService.selectList(deptWrapper);
            for (SysDept dept : sysDepts) {
                communityIds.add(dept.getDeptId() == null ? "" : dept.getDeptId().toString());
            }
        }
        return communityIds;
    }

    /**
     * 根据角色id获取对应的用户列表
     *
     * @param roleId 角色ID
     * @return 用户列表
     */
    @Override
    public List<SysUser> selectListByRoleId(Integer roleId, String communityId) {

        return sysUserMapper.selectListByRoleId(roleId, communityId);
    }

    @Override
    public List<UserVO> selectByUserName(String userName) {
        return sysUserMapper.selectByUserName(userName);
    }

//    @Override
//    public List<CompanyBean> getCompanySCurrentUser(String currentUserName) {
//        List<CommunityInfo> communityInfos = new ArrayList<>();
//        if(CommonConstant.MANAGE_NAME.equalsIgnoreCase(currentUserName)){
//            EntityWrapper entityWrapper = new EntityWrapper();
//            entityWrapper.eq(CommonConstant.DEL_FLAG,CommonConstant.STATUS_NORMAL);
//            communityInfos = communityInfoService.selectList(entityWrapper);
//        }else{
//            communityInfos= communityInfoService.getCommunitysByCurrentUser(currentUserName);
//        }
//
//        List<CompanyBean> result = new ArrayList<>();
//        CompanyBean companyBean = new CompanyBean();
//        CompanyBean dept = new CompanyBean();
//        companyBean.setLabel("园区");
//        dept.setLabel("企业");
//        List<SelectBean> selectBeans = new ArrayList<>();
//        List<SelectBean> deptBeans = new ArrayList<>();
//        for(CommunityInfo info : communityInfos){
//            SelectBean selectBean = new SelectBean();
//            selectBean.setLabel(info.getName());
//            selectBean.setValue(info.getId()==null?"":info.getId().toString());
//            selectBeans.add(selectBean);
//            //返回园区下的企业信息
//            EntityWrapper entityWrapper = new EntityWrapper();
//            entityWrapper.eq(CommonConstant.DEL_FLAG,CommonConstant.STATUS_NORMAL);
//            entityWrapper.eq("parent_id",info.getId());
//            entityWrapper.eq("dept_property",CommonConstant.STATUS_DEL);
//            List<SysDept> sysDepts = sysDeptService.selectList(entityWrapper);
//            for(SysDept sysDept : sysDepts){
//                SelectBean qy = new SelectBean();
//                qy.setLabel(sysDept.getName());
//                qy.setValue(sysDept.getDeptId()==null?"":sysDept.getDeptId().toString());
//                deptBeans.add(qy);
//            }
//        }
//        //如果园区为空，直接加载本企业节点
//        if(communityInfos==null||communityInfos.size()==0){
//            List<SysDept> sysDepts = communityInfoService.getDeptsByCurrentUser(currentUserName);
//            for(SysDept sysDept : sysDepts){
//                SelectBean qy = new SelectBean();
//                qy.setLabel(sysDept.getName());
//                qy.setValue(sysDept.getDeptId()==null?"":sysDept.getDeptId().toString());
//                deptBeans.add(qy);
//            }
//        }
//        companyBean.setOptions(selectBeans);
//        dept.setOptions(deptBeans);
//        if(companyBean.getOptions()!=null&&companyBean.getOptions().size()>0){
//            result.add(companyBean);
//        }
//        if(dept.getOptions()!=null&&dept.getOptions().size()>0){
//            result.add(dept);
//        }
//
//        return result;
//    }

    @Override
    public List<SysUser> selectUsersListByDept(String parentId) {
        return sysUserMapper.selectUsersListByDept(parentId);
    }

    @Override
    public List<SelectBean> getCompanyTreeCurrentUser(String currentUserName) {
        List<CommunityInfo> communityInfos = new ArrayList<>();
        List<SelectBean> trees = new ArrayList<>();
        EntityWrapper entityWrapper = new EntityWrapper();
        if (CommonConstant.MANAGE_NAME.equalsIgnoreCase(currentUserName)) {
            EntityWrapper wrapper = new EntityWrapper();
            wrapper.eq(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
            communityInfos = communityInfoService.selectList(wrapper);
        } else {
            UserVO user= sysUserMapper.selectUserVoByUsername(currentUserName);
            communityInfos = communityInfoService.getCommunitysByCurrentUser(currentUserName);
            entityWrapper.in("company_id", user.getCommunityList().stream().map(CommunityInfoBean::getCommunityId).collect(Collectors.joining(",")));
        }
        for (CommunityInfo community : communityInfos) {
            SelectBean tree = new SelectBean();
            tree.setLabel(community.getName());
            tree.setValue(community.getId().toString());
            tree.setId(community.getId());
            tree.setParentId(0);
            trees.add(tree);
        }

        entityWrapper.eq(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
        entityWrapper.eq("dept_property", CommonConstant.DEPTPROPERTY_COMPANY);
        List<SysDept> sysDepts = sysDeptService.selectList(entityWrapper);
        for (SysDept dept : sysDepts) {
            SelectBean node = new SelectBean();
            node.setId(dept.getDeptId());
            node.setParentId(dept.getParentId());
            node.setLabel(dept.getName());
            node.setValue(dept.getDeptId().toString());
            trees.add(node);
        }
        return TreeUtil.bulid(trees, 0);
//        return TreeUtil.bulid(trees, 0).stream().map(selectBean -> {
//            if (selectBean.getChildren().isEmpty()) {
//                selectBean.setChildren(null);
//            }
//            return selectBean;
//        }).collect(Collectors.toList());
    }
}
